<?php

namespace app\common\middleware;

/**
 * Class UnDuplicate
 * @package app\common\middleware
 * 防止接口重复提交
 */
class UnDuplicate
{
    public static $duplicateKey = null;

    public static $duplicateValue = 1;

    private $cachePrefix = 'UnDuplicate:';

    public function handle($request, \Closure $next, $params=[])
    {
        // 默认缓存驱动必须是redis 才可使用
        $cacheDriver = config('cache.default');
        if ($cacheDriver != 'redis') {
            return $next($request);
        }
        // 构造请求key
        $param = request()->param();
        $input = request()->getInput();
        $url = request()->url();
        UnDuplicate::$duplicateKey = $this->cachePrefix . str_replace('/', '', request()->baseUrl()) . md5(json_encode($param) . json_encode($input) . $url);

        // 接口锁时间
        $expire = !empty($params['expire']) && is_int($params['expire']) ? $params['expire'] : 60;

        // 存储请求key
        $setResult = cache()->handler()->set(UnDuplicate::$duplicateKey, UnDuplicate::$duplicateValue, ['nx', 'ex' => $expire]);
        if (!$setResult) {
            UnDuplicate::$duplicateKey = null;
            exception('请求过于频繁，请稍后再试');
        }
        return $next($request);
    }

    /**
     * @return bool
     * 是否需要限制表单重复提交
     */
    public static function isNeedUnlockDuplicate()
    {
        $cacheDriver = config('cache.default');

        return !empty(UnDuplicate::$duplicateKey) && $cacheDriver == 'redis';
    }

    /**
     * 解锁接口重复调用
     */
    public static function unlock()
    {
        $script = 'if redis.call("get",KEYS[1]) == ARGV[1] then return redis.call("del",KEYS[1]) else return 0 end';
        //使用lua脚本保证原子性
        cache()->handler()->eval($script, [UnDuplicate::$duplicateKey, UnDuplicate::$duplicateValue], 1);
    }
}